<?php
/**
 *
 *
 * @author Zeon <scplay@gmail.com>
 * @date 2018/12/19 14:42
 * @copyright PanxSoft Inc.
 */

namespace App\Services\MobileApp;

use App\Models\Currency;
use App\Models\Language;
use App\Models\Store;
use App\Services\Customers\AppCustomer;
use App\Services\Utils\Guard;

/**
 * Class AppEnv
 *
 * Direwolf App 的环境变量
 *
 * @package App\Services\MobileApp
 */
class AppEnv
{
    const GLOBAL_REQUEST_KEY_STORE_ID = 'store_id';

    const GLOBAL_REQUEST_KEY_LANGUAGE = 'language';

    const GLOBAL_REQUEST_KEY_CURRENCY = 'currency';

    const REQUEST_PLATFORM = 'platform';
    const PLATFORM_IOS = 'ios';
    const PLATFORM_ANDROID = 'android';

    /**
     * @var Store|null
     */
    static private $store;

    /**
     * @var Language|null
     */
    static private $language;

    /**
     * @var Currency|null
     */
    static private $currency;

    /**
     * @return int
     */
    public static function languageId(): int
    {
        return self::language()->language_id;
    }

    /**
     * @return Language
     */
    public static function language(): Language
    {
        if (! isset(self::$language)) {
            self::$language = self::findLanguage();
        }

        return self::$language;
    }

    private static function findLanguage(): Language
    {
        // 请求参数优先
        $code = request()->get(self::GLOBAL_REQUEST_KEY_LANGUAGE);
        if ($code && ($find = Language::memoWhereFirst(compact('code')))) {
            return $find;
        }

        // 用户数据其次
        if (Guard::hasJwtToken()
            && Guard::customer()
            && ($find = Language::memoFind(Guard::customer()->language_id))) {
            return $find;
        }

        // 未登录使用店铺的默认语言
        return Language::getStoreDefault(self::storeId());
    }

    /**
     * @return int
     */
    public static function storeId(): int
    {
        return self::store()->store_id;
    }

    /**
     * 店铺 ID 会根据请求参数 或 token 对应的客户初始化成不同的值
     *
     * @return Store
     */
    public static function store(): Store
    {
        if (! isset(self::$store)) {
            self::$store = self::findStore();
        }

        return self::$store;
    }

    private static function findStore(): Store
    {
        if (Guard::hasJwtToken() && Guard::customer() && Guard::customer()->store) {
            return Guard::customer()->store;
        }

        $store_id = (int) request()->get(self::GLOBAL_REQUEST_KEY_STORE_ID);
        if ($store_id && ($find = Store::memoFind($store_id))) {
            return $find;
        }

        if ($find = Store::findByHost()) {
            return $find;
        } else {
            return Store::default();
        }
    }

    /**
     * @return Currency
     */
    public static function currency(): Currency
    {
        if (! isset(self::$currency)) {
            self::$currency = self::findCurrency();
        }

        return self::$currency;
    }

    private static function findCurrency(): Currency
    {
        $code = request()->get(self::GLOBAL_REQUEST_KEY_CURRENCY)
            ?: Currency::getStoreSettingCurrencyCode(self::storeId());

        if ($code && ($currency = Currency::memoWhereFirst(compact('code')))) {
            return $currency;
        } else {
            throw new \LogicException("Currency code [$code] missing in database");
        }
    }

    public static function customerGroupId(): int
    {
        return AppCustomer::groupId();
    }

    public static function platform(): ?string
    {
        return request(self::REQUEST_PLATFORM);
    }
}